﻿#include "memory_pool.h"
#include <cstdlib>

using namespace RemoteObj;

MemoryPool::MemoryPool(): _chunk_count(0)
{
    for(int32_t size = MIN_SIZE; size <= MAX_SIZE; size *= 2)
        ++_chunk_count;
    //_chunk_list=(MemoryChunk**)malloc(sizeof(MemoryChunk*)*_chunk_count);

    _chunk_list = new MemoryChunk*[_chunk_count];
    int32_t index = 0;
    for(int32_t size = MIN_SIZE; size <= MAX_SIZE; size *= 2)
    {
        _chunk_list[index++] = new MemoryChunk(size,1000);
    }
}

MemoryPool::~MemoryPool()
{
    for(int32_t index = 0; index < _chunk_count; ++index)
    {
        delete _chunk_list[index];
    }
    //free(_chunk_list);
    delete[] _chunk_list;
}

void* MemoryPool::malloc(int32_t size)
{
    if(size > MAX_SIZE)
    {
        return do_malloc(size);
    }
    else
    {
        int32_t index = 0;
        for(int32_t tsize = MIN_SIZE; tsize <= MAX_SIZE; tsize *= 2)
        {
            if(tsize >= size)
                break;
            ++index;
        }
        return _chunk_list[index]->malloc();
    }
}

void MemoryPool::free(void* mem)
{
    if(!do_free(mem))
        MemoryChunk::free(mem);
}

void* MemoryPool::do_malloc(int32_t size)
{
    MemoryHeap* heap = (MemoryHeap*)::malloc(sizeof(HeapHeader)+size);
    if(heap)
    {
        heap->header.size = size;
        return &heap->buffer;
    }
    return NULL;
}

bool MemoryPool::do_free(void* mem)
{
    MemoryHeap* heap=(MemoryHeap*)((char*)mem-sizeof(HeapHeader));
    if(heap->header.size > MAX_SIZE)
    {
        ::free(heap);
        return true;
    }
    return false;
}
